package com.dyava.commons.file;

import com.dyava.commons.lang.ByteUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Map.Entry;
import java.util.TreeMap;

/**
 * 文件类型探测工具
 */
public class FileTypeUtils {

	// 缓存文件头信息-文件头信息
	public static final TreeMap<String, String> mFileTypes = new TreeMap<String, String>();

	static {
		// images
		mFileTypes.put("FFD8FF", "jpg");
		mFileTypes.put("89504E47", "png");
		mFileTypes.put("47494638", "gif");
		mFileTypes.put("49492A00", "tif");
		mFileTypes.put("424D", "bmp");
		//
		mFileTypes.put("41433130", "dwg"); // CAD
		mFileTypes.put("38425053", "psd");
		mFileTypes.put("7B5C727466", "rtf"); // 日记本
		mFileTypes.put("44656C69766572792D646174653A", "eml"); // 邮件
		mFileTypes.put("D0CF11E0", "doc");
		mFileTypes.put("5374616E64617264204A", "mdb");
		mFileTypes.put("252150532D41646F6265", "ps");
		mFileTypes.put("255044462D312E", "pdf");
		mFileTypes.put("504B03040A", "docx");
		
		mFileTypes.put("57415645", "wav");
		mFileTypes.put("41564920", "avi");
		mFileTypes.put("2E524D46", "rm");
		mFileTypes.put("000001BA", "mpg");
		mFileTypes.put("000001B3", "mpg");
		mFileTypes.put("6D6F6F76", "mov");
		mFileTypes.put("3026B2758E66CF11", "asf");
		mFileTypes.put("4D546864", "mid");
		
		mFileTypes.put("1F8B08", "gz");
		mFileTypes.put("504B030414", "zip");
		mFileTypes.put("52617221", "rar");
	}
	
	private static String getTypeNameByHeadHex(String headHex){
		for(Entry<String, String> entry : mFileTypes.descendingMap().entrySet()){
			String type = entry.getKey();
			if(headHex.startsWith(type)){
				return entry.getValue();
			}
		}
		return null;
	}
	
	/**
	 * 是否图片文件
	 * @param typeName
	 * @return
	 */
	public static boolean isImage(String typeName){
		if(
			"jpg".equalsIgnoreCase(typeName)|| 
			"png".equalsIgnoreCase(typeName)|| 
			"jpg".equalsIgnoreCase(typeName)|| 
			"gif".equalsIgnoreCase(typeName)|| 
			"tif".equalsIgnoreCase(typeName)|| 
			"bmp".equalsIgnoreCase(typeName)
		){
			return true;
		}else{
			return false;
		}
	}

	/**
	 * 根据数组获得文件类型
	 * @param data
	 * @return 返回null时无法判断
	 */
	public static String getFileTypeByByteArray(byte[] data){
		String headHex = ByteUtils.bytesToHexString(data, 0, 16,true);
		String fileType = getTypeNameByHeadHex(headHex);
		return fileType;
	}
	/**
	 * 根据文件获得文件类型
	 * @param file
	 * @return 无法判断时，以文件名判定
	 * @throws IOException
	 */
	public static String getFileTypeByFile(File file) throws IOException{
		FileInputStream is = null;
		String headHex = null;
		try {
			is = new FileInputStream(file);
			byte[] b = new byte[16];
			int len = is.read(b, 0, b.length);
			headHex = ByteUtils.bytesToHexString(b,0,len,true);
		} catch (IOException e) {
			e.printStackTrace();
			throw e;
		} finally {
			IOUtils.closeQuietly(is);
		}
		String fileType = getTypeNameByHeadHex(headHex);
		if(StringUtils.isNotEmpty(fileType)){
			return fileType;
		}else{
			return FilenameUtils.getExtension(file.getName()).toLowerCase();
		}
	}


}
